package com.cn.web.user.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.http.HttpUtil;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.cn.annoation.Logs;
import com.cn.auth.AuthVo;
import com.cn.config.SmsCodeTemplateConfig;
import com.cn.error.ErrorConstantUtil;
import com.cn.exception.MyException;
import com.cn.global.GlobalParamterUtil2;
import com.cn.msg.ResultMsg;
import com.cn.redis.RedisHandleUtil;
import com.cn.sms.SmsSendUtil;
import com.cn.user.UserDO;
import com.cn.util.*;
import com.cn.validate.decode.AesEncryptUtils;
import com.cn.web.user.service.LoginService;
import com.cn.web.user.service.UserService;
import com.cn.web.user.service.impl.LoginServiceImpl;
import com.cn.web.user.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;

/**
 * description: LoginController <br>
 * date: 21.12.14 11:25 <br>[
 * author: cn_yaojin <br>
 * version: 1.0 <br>
 */
@RestController
@RequestMapping(value = "admin/login")
@Api(tags = "用户中心--登录")
@Slf4j
public class LoginController extends BaseController {

    @Autowired
    private LoginService loginService;

    @Autowired
    private UserService userService;

    @Autowired
    private SmsCodeTemplateConfig smsCodeTemplateConfig;


    @Logs(value = "账号密码登录", desc = "用户中心")
    @ApiOperation(value = "账号密码登录")
    @PostMapping(value = "login")
    public ResultMsg<AuthVo> login(
            @RequestBody @Validated UserLoginDTO userLogin
    ) {
//        checkCode(userLogin);
        AuthVo<UserDO> authVo = this.loginService.login(userLogin, LoginDeviceTypeEnum.pc.name());
        removeCode(userLogin);
        return ResultMsg.builder().setData(authVo.setUser(null));
    }


    @Logs(value = "忘记密码", desc = "用户中心")
    @ApiOperation(value = "忘记密码")
    @PostMapping(value = "forgetPass")
    public ResultMsg forgetPass(
            @RequestBody @Validated UserForgetPassDTO info
    ) {
        //验证短信码
        checkSmsCode(info.getPhone(), info.getCode());
        this.loginService.forgetPass(info);
        delSmsCode(info.getPhone());
        return ResultMsg.builder();
    }

    @Logs(value = "发送短信验证码", desc = "用户中心")
    @ApiOperation(value = "短信验证码")
    @GetMapping(value = "sendSmsCode")
    public ResultMsg sendSmsCode(
            @ApiParam(name = "phone") @RequestParam(required = false) String phone,
            @ApiParam(name = "code", value = "图形验证码，预留") @RequestParam(required = false) String code
    ) {
        phone = AesEncryptUtils.decrypt(phone);
        sendSmsCode(phone);
        return ResultMsg.builder();
    }

    @Logs(value = "退出登录", desc = "用户中心", model = 1)
    @ApiOperation(value = "退出登录")
    @GetMapping(value = "logout")
    public ResultMsg logout() {
        String token = StpUtil.getTokenValue();
        StpUtil.logoutByTokenValue(token);
        return ResultMsg.builder();
    }

    @ApiOperation(value = "图形验证码")
    @GetMapping(value = "/random")
    public void random(
            @ApiParam(name = "randomKey") @RequestParam String randomKey
    ) throws IOException {
        String random = RandomUtil.getRandom(4);
        String cacheKey = getKey(randomKey);
        RedisHandleUtil.add(cacheKey, random, 120);
        ValidateCodeUtil.validateCode(response, random);
    }

    @ApiOperation(value = "加密")
    @GetMapping(value = "testPwd")
    public ResultMsg testPwd(
            @ApiParam(name = "data") @RequestParam String data
    ) {
        String txt = LoginServiceImpl.md5(data);
        return ResultMsg.builder(txt);
    }

    private String getKey(String randomKey) {
        String key = GlobalParamterUtil2.get().getSmsKeySpace() + ":" + randomKey;
        return key;
    }

    private void checkCode(UserLoginDTO userLogin) {
        String cacheKey = getKey(userLogin.getRandomKey());
        String value = RedisHandleUtil.get(cacheKey);
        if (!userLogin.getCode().equalsIgnoreCase(value)) {
            throw new MyException(ErrorConstantUtil.VALIDATE_CODE_ERROR);
        }
    }

    private void removeCode(UserLoginDTO userLogin) {
        String cacheKey = getKey(userLogin.getRandomKey());
        RedisHandleUtil.del(cacheKey);
    }

    /**
     * 发送短信验证码
     *
     * @param phone
     */
    public static void sendSmsCode(String phone) {
        String smsCode = getSmsCode(phone);
        Map<String, String> msg = new HashMap<>();
        msg.put("code", smsCode);
        SendSmsResponse response = (SendSmsResponse) SmsSendUtil.send(phone, GsonUtil.toJson(msg));
        if (StringUtils.isNotEmpty(response.getBody().getCode()) && !response.getBody().getCode().equalsIgnoreCase("ok")) {
            throw new MyException(ConstanUserUtil.SMS_SEND_ERROR);
        }
    }

    public void sendRegisterSms(String phone) {
        Map<String, String> msg = new HashMap<>();
        msg.put("user", "");
        try {
            SendSmsResponse response = (SendSmsResponse) SmsSendUtil.send(phone, GsonUtil.toJson(msg), this.smsCodeTemplateConfig.getNewUserNotify());
        } catch (Exception e) {
            log.error("注册用户成功，发送短信失败：" + e.getMessage());
        }

    }

    /**
     * 获取短信验证码
     *
     * @param phone
     * @return
     */
    public static String getSmsCode(String phone) {
        String smsCode = cn.hutool.core.util.RandomUtil.randomNumbers(4);
        RedisHandleUtil.add(getSmsCodeKey(phone), smsCode, 300);
        return smsCode;
    }

    /**
     * 校验短信验证码
     *
     * @param key
     * @param code
     */
    public static void checkSmsCode(String key, String code) {
        String smsCode = RedisHandleUtil.get(getSmsCodeKey(key));
        if (StringUtils.isEmpty(smsCode) || !smsCode.equals(code)) {
            throw new MyException(ConstanUserUtil.PHONE_CODE_ERROR);
        }
    }

    /**
     * 删除短信验证码
     *
     * @param key
     */
    public static void delSmsCode(String key) {
        RedisHandleUtil.del(getSmsCodeKey(key));
    }

    public static String getSmsCodeKey(String randomKey) {
        String key = GlobalParamterUtil2.get().getSmsKeySpace() + ":" + randomKey;
        return key;
    }


    public static void main(String[] args) {
        String x = "姚进";
        ThreadLocalRandom random = ThreadLocalRandom.current();
//        for (int i = 1; i < 100; i++) {
//            System.out.println(random.nextInt(10));
//        }
        String[] IPV4_INTERFACE_VALUES = {"https://ip.3322.net", "https://4.ipw.cn"};
        String ipv4Interface = Arrays.stream(IPV4_INTERFACE_VALUES).findAny().get();
        String ipv4 = HttpUtil.get(ipv4Interface);
        System.out.println(ipv4);

        System.out.println(HttpUtil3.doGet("https://ip.3322.net"));

    }

}
